class WebSocketClient {
  constructor(options = {}) {
    this.url = options.url || ''
    this.socketKey = options.socketKey || 'defaultSocket'
    this.isPublicSocket = options.socketKey === 'courseSocket'
    this.reconnectInterval = options.reconnectInterval || 3000
    this.maxReconnectAttempts = options.maxReconnectAttempts || 5
    this.maxConnections = options.maxConnections || 3
    
    this.ws = null
    this.reconnectCount = 0
    this.connectionCount = 0
    this.reconnectTimer = null
    this.isConnecting = false
    this.forceClose = false
    
    // 错误统计
    this.errorStats = {
      totalErrors: 0,
      tlsErrors: 0,
      networkErrors: 0,
      otherErrors: 0,
      lastError: null,
      lastErrorTime: null
    }
    
    this.onMessageCallback = null
    this.onOpenCallback = null
    this.onErrorCallback = null
    this.onCloseCallback = null
    this.onTokenInvalidCallback = null
    this.needHeartbeat = options.needHeartbeat || false
  }

  checkToken() {
    const token = uni.getStorageSync('token')
    
    if (this.isPublicSocket) {
      return true
    }
    
    if (!token) {
      console.log('未找到token，取消连接')
      return false
    }
    return true
  }

  checkExistingConnection() {
    const socketInfo = uni.getStorageSync(this.socketKey)
    if (socketInfo && socketInfo.connected) {
      console.log('WebSocket已经存在连接')
      return true
    }
    return false
  }

  updateConnectionStatus(connected) {
    uni.setStorageSync(this.socketKey, {
      connected,
      timestamp: Date.now()
    })
  }

  // 记录错误信息
  logError(error, type = 'other') {
    this.errorStats.totalErrors++
    this.errorStats.lastError = error
    this.errorStats.lastErrorTime = new Date().toISOString()
    
    switch(type) {
      case 'tls':
        this.errorStats.tlsErrors++
        console.error('TLS错误:', {
          error,
          url: this.url,
          errorCode: error.errCode,
          errorMsg: error.errMsg,
          timestamp: this.errorStats.lastErrorTime
        })
        break
      case 'network':
        this.errorStats.networkErrors++
        console.error('网络错误:', {
          error,
          url: this.url,
          errorCode: error.errCode,
          errorMsg: error.errMsg,
          timestamp: this.errorStats.lastErrorTime
        })
        break
      default:
        this.errorStats.otherErrors++
        console.error('WebSocket错误:', {
          error,
          url: this.url,
          errorCode: error.errCode,
          errorMsg: error.errMsg,
          timestamp: this.errorStats.lastErrorTime
        })
    }
  }

  // 获取错误诊断信息
  getErrorDiagnostics() {
    return {
      ...this.errorStats,
      currentState: {
        isConnecting: this.isConnecting,
        reconnectCount: this.reconnectCount,
        connectionCount: this.connectionCount,
        forceClose: this.forceClose
      }
    }
  }

  connect() {
    if (this.checkExistingConnection()) {
      console.log('复用现有WebSocket连接')
      return
    }

    if (this.isConnecting) {
      console.log('正在连接中，跳过本次连接')
      return
    }
    
    if (!this.checkToken()) {
      this.forceClose = true
      this.onTokenInvalidCallback && this.onTokenInvalidCallback()
      return
    }

    if (this.connectionCount >= this.maxConnections) {
      console.log('达到最大连接次数，停止重连')
      this.forceClose = true
      return
    }
    
    this.isConnecting = true
    
    try {
      this.connectionCount++
      console.log(`第${this.connectionCount}次连接`, {
        url: this.url,
        timestamp: new Date().toISOString()
      })
      
      const token = this.isPublicSocket ? 
        (uni.getStorageSync('token') || 'anyUserSocket') : 
        uni.getStorageSync('token')
      
      this.ws = uni.connectSocket({
        url: this.url+'?Authorization='+token,
        complete: () => {
          this.isConnecting = false
        }
      })

      this.ws.onOpen(() => {
        console.log('WebSocket连接已打开', {
          url: this.url,
          timestamp: new Date().toISOString()
        })
        this.updateConnectionStatus(true)
        this.reconnectCount = 0
        if(this.needHeartbeat) {
          this.startHeartbeat()
        }
        this.onOpenCallback && this.onOpenCallback()
      })
      
      this.ws.onMessage((res) => {
        try {
          const data = JSON.parse(res.data)
          if (data.code === 401 || data.msg === 'token invalid') {
            console.log('Token失效，断开连接', {
              data,
              timestamp: new Date().toISOString()
            })
            this.forceClose = true
            this.close()
            this.onTokenInvalidCallback && this.onTokenInvalidCallback()
            return
          }
        } catch (e) {
          console.warn('消息解析失败:', {
            rawData: res.data,
            error: e.message,
            timestamp: new Date().toISOString()
          })
        }
        this.onMessageCallback && this.onMessageCallback(res)
      })
      
      this.ws.onError((error) => {
        // 判断错误类型
        if (error.errMsg && error.errMsg.includes('TLS handshake failed')) {
          this.logError(error, 'tls')
        } else if (error.errCode === 1004 || error.errCode === 1005) {
          this.logError(error, 'network')
        } else {
          this.logError(error)
        }
        
        this.onErrorCallback && this.onErrorCallback(error)
        if (!this.forceClose) {
          this.reconnect()
        }
      })
      
      this.ws.onClose(() => {
        console.log('WebSocket连接已关闭', {
          url: this.url,
          timestamp: new Date().toISOString(),
          errorStats: this.getErrorDiagnostics()
        })
        this.updateConnectionStatus(false)
        this.onCloseCallback && this.onCloseCallback()
        if (!this.forceClose) {
          this.reconnect()
        }
      })
      
    } catch (error) {
      this.logError(error)
      this.isConnecting = false
      if (!this.forceClose) {
        this.reconnect()
      }
    }
  }

  // 重连机制
  reconnect() {
    if (this.forceClose) return
    if (this.reconnectCount >= this.maxReconnectAttempts) {
      console.log('达到最大重连次数')
      this.forceClose = true
      return
    }
    
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer)
    }
    
    this.reconnectTimer = setTimeout(() => {
      console.log(`第${this.reconnectCount + 1}次重连...`)
      this.reconnectCount++
      this.connect()
    }, this.reconnectInterval)
  }

  // 心跳检测
  startHeartbeat() {
    if (this.heartbeatTimer) {
      clearInterval(this.heartbeatTimer)
    }
    
    this.heartbeatTimer = setInterval(() => {
      this.send({ type: 'heartbeat', data: 'ping' })
    }, this.heartbeatInterval)
  }

  // 发送消息
  send(data) {
    if (!this.ws) {
      console.error('WebSocket未连接')
      return
    }
    
    try {
      const messageData = {
        ...data,
        timestamp: Date.now()
      }
      
      this.ws.send({
        data: typeof messageData === 'string' ? messageData : JSON.stringify(messageData),
        fail: (error) => {
          console.error('发送消息失败:', error)
        }
      })
    } catch (error) {
      console.error('发送消息错误:', error)
    }
  }

  // 关闭连接
  close() {
    this.forceClose = true
    this.updateConnectionStatus(false)
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer)
    }
    
    if (this.ws) {
      this.ws.close({
        success: () => {
          console.log('WebSocket已关闭')
        },
        fail: (error) => {
          console.error('关闭WebSocket失败:', error)
        }
      })
    }
  }

  // 事件监听器
  onMessage(callback) {
    this.onMessageCallback = callback
  }

  onOpen(callback) {
    this.onOpenCallback = callback
  }

  onError(callback) {
    this.onErrorCallback = callback
  }

  onClose(callback) {
    this.onCloseCallback = callback
  }

  onTokenInvalid(callback) {
    this.onTokenInvalidCallback = callback
  }

  // 重置连接状态
  reset() {
    this.forceClose = false
    this.connectionCount = 0
    this.reconnectCount = 0
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer)
    }
  }
}

export default WebSocketClient 